﻿Imports SonOVB.Samples.ComicSyndication.Extensions
Imports System.Configuration.Provider
Imports System.Collections.Specialized
Imports System.IO
Imports System.Web

Namespace Providers


    Public Class FileSystemComicProvider
        Inherits ComicProvider

        ''' <summary>
        '''  Image 的名称
        ''' </summary>
        ''' <remarks></remarks>
        Private Const STR_ImageFileName As String = "image.*"
        ''' <summary>
        ''' 描述文件名称
        ''' </summary>
        ''' <remarks></remarks>
        Private Const STR_DescriptionFileName As String = "description.txt"


        ''' <summary>
        ''' 表示 卷 所使用的开头
        ''' </summary>
        ''' <remarks></remarks>
        Const STR_Vol = "Vol*"

        ''' <summary>
        ''' 表示 章 所使用的开头
        ''' </summary>
        ''' <remarks></remarks>
        Const STR_Chapter = "Chapter*"



        ''' <summary>
        ''' 图片路径
        ''' </summary>
        ''' <remarks></remarks>
        Private _comicPath As String

        ''' <summary>
        ''' 图片路径
        ''' </summary>
        Public ReadOnly Property ComicsPath() As String
            Get
                Return _comicPath
            End Get
        End Property


        ''' <summary>
        ''' 初始化
        ''' </summary>
        ''' <param name="name"></param>
        ''' <param name="config"></param>
        ''' <remarks></remarks>
        Public Overrides Sub Initialize(ByVal name As String, ByVal config As NameValueCollection)
            MyBase.Initialize(name, config)

            Dim s As String = config.Get("comicsPath")
            If s Is Nothing Then
                Throw New ProviderException(My.Resources.FileSystemComicProvider.ComicsPathNotSet)
            End If

            If Not Directory.Exists(s) Then
                Throw New ProviderException(My.Resources.FileSystemComicProvider.ComicsPathNotExists)
            End If

            Dim info As New DirectoryInfo(s)
            _comicPath = info.FullName
        End Sub



        ''' <summary>
        ''' 获取 全部漫画
        ''' </summary>
        ''' <returns></returns>
        Public Overrides Function GetComics() As System.Collections.Generic.List(Of Comic)
            Dim dirs = My.Computer.FileSystem.GetDirectories(Me._comicPath, FileIO.SearchOption.SearchTopLevelOnly, "*")

            Dim list As New List(Of Comic)

            For Each d In dirs

                list.Add(MakeComic(d))
            Next

            Return list
        End Function


#Region "函数"


        ''' <summary>
        ''' 生成绝对路径 + \
        ''' </summary>
        ''' <param name="basePath"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function MakeBasePath(ByVal basePath As String) As String
            Return If((basePath.Length - basePath.LastIndexOf(IO.Path.DirectorySeparatorChar)) > 1, basePath & IO.Path.DirectorySeparatorChar, basePath)
        End Function
        ''' <summary>
        ''' 设置ItemBase
        ''' </summary>
        ''' <param name="basePath">记住路径</param>
        ''' <param name="di">目录</param>
        ''' <param name="item"></param>
        ''' <remarks></remarks>
        Private Sub SetItemBase(ByVal basePath As String, ByVal di As DirectoryInfo, ByVal item As SonOVB.Samples.ComicSyndication.ComicProvider.ItemBase)

            Dim bp = MakeBasePath(basePath)

            Dim uri As New Uri(bp)

            Dim path As Uri = New Uri(di.FullName)

            Dim relativeUri As Uri = uri.MakeRelativeUri(path)

            Dim relativePath As String = HttpUtility.UrlDecode(relativeUri.ToString) ' relativeUri.ToString.Substring(0, relativeUri.ToString.LastIndexOf(".", StringComparison.Ordinal)).Replace("/", ";")

            item.Id = relativePath

            item.Title = di.Name

            Dim imagefile = di.GetFiles(STR_ImageFileName, SearchOption.TopDirectoryOnly).FirstOrDefault


            item.Image = If(imagefile IsNot Nothing, New Uri(imagefile.FullName), GetNoImage)

            item.ImageMimeType = GetMIMEType(item.Image.ToString)


            item.ItemUrl = New Uri(di.FullName)

            item.DateCreated = di.CreationTime
            item.DateModified = di.LastWriteTime
        End Sub


#Region "Making...."

        ''' <summary>
        ''' 生成 Comic
        ''' </summary>
        ''' <param name="d"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function MakeComic(ByVal d As String) As SonOVB.Samples.ComicSyndication.ComicProvider.Comic

            Dim di = My.Computer.FileSystem.GetDirectoryInfo(d)

            Dim c = New Comic()

            SetItemBase(ComicsPath, di, c)

            Dim descfile As String = Path.Combine(di.FullName, STR_DescriptionFileName)
            c.Description = If(My.Computer.FileSystem.FileExists(descfile), My.Computer.FileSystem.ReadAllText(descfile), "")

            '设置Title

            c.Title = String.Format(My.Resources.FileSystemComicProvider.ComicTitle, c.Title)

            Return c
        End Function


        ''' <summary>
        '''  生成 内容
        ''' </summary>
        ''' <param name="comicId">漫画ID</param>
        ''' <param name="comicPath">漫画 路径</param>
        ''' <param name="type">内容类型</param>
        ''' <param name="path">内容路径</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function MakeContent(ByVal comicId As String, _
                                     ByVal comicPath As String, _
                                     ByVal type As SonOVB.Samples.ComicSyndication.ComicProvider.ContentType, _
                                     ByVal path As String) As SonOVB.Samples.ComicSyndication.ComicProvider.ComicContent

            Dim di = My.Computer.FileSystem.GetDirectoryInfo(path)

            Dim content = New ComicContent(type) With {.ComicId = comicId}

            SetItemBase(comicPath, di, content)

            With content
                .Size = 0
                .MimeType = ""
            End With

            Dim files = di.GetFiles().Where(Function(x) (x.Extension = ".jpg" OrElse x.Extension = ".png" OrElse x.Extension = ".gif" OrElse x.Extension = ".bmp"))

            For Each fi In files

                '添加图片
                Dim p As Picture = MakePicture(comicId, content.Id, di.FullName, content.ItemType, fi)

                content.Items.Add(p)

            Next

            Dim image = files.FirstOrDefault

            If image IsNot Nothing Then
                content.Image = New Uri(image.FullName)
                content.ImageMimeType = GetMIMEType(image.FullName)
            End If

            '设置Title
            If type = ContentType.Chapter Then
                content.Title = String.Format(My.Resources.FileSystemComicProvider.ChapterTitle, content.Title.Replace(STR_Chapter.Substring(0, STR_Chapter.Length - 1), "").Trim)
            ElseIf type = ContentType.Vol Then
                content.Title = String.Format(My.Resources.FileSystemComicProvider.VolTitle, content.Title.Replace(STR_Vol.Substring(0, STR_Vol.Length - 1), "").Trim)
            End If


            Return content
        End Function



        ''' <summary>
        ''' 生成 Picture
        ''' </summary>
        ''' <param name="comicId">漫画ID</param>
        ''' <param name="contentId">容器ID</param>
        ''' <param name="basepath">容器路径</param>
        ''' <param name="ItemType">类型</param>
        ''' <param name="info">文件信息</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function MakePicture(ByVal comicId As String, ByVal contentId As String, ByVal basepath As String, ByVal ItemType As ContentType, ByVal info As FileInfo) As Picture
            Dim p As New Picture()

            Dim bp = MakeBasePath(basepath)
            ' Set picture ID
            Dim uri As New Uri(bp)
            Dim relativeUri As Uri = uri.MakeRelativeUri(New Uri(info.FullName))
            Dim relativePath As String = relativeUri.ToString.Replace("/", ";") 'ToString.Substring(0, relativeUri.ToString.LastIndexOf(".", StringComparison.Ordinal))
            p.Id = relativePath


            p.ItemId = contentId
            p.ItemType = ItemType
            p.ComicId = comicId
            p.FileName = info.Name
            p.FileExtension = info.Extension
            p.ItemUrl = New Uri(info.FullName)
            p.Size = CInt(info.Length)
            p.MimeType = GetMIMEType(p.FileExtension)
            p.DateCreated = info.CreationTime
            p.DateModified = info.LastWriteTime
            Return p
        End Function


#End Region



#End Region

#Region "继承实现"




        ''' <summary>
        ''' 获取漫画
        ''' </summary>
        Public Overrides Function GetComicById(ByVal comicId As String) As Comic
            If comicId.IsNotNullOrEmpty Then

                Dim s As String = comicId.Replace(";", "/")
                Dim path As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(s, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(path) Then Return Nothing


                Return MakeComic(path)
            Else
                Return Nothing
            End If
        End Function

        '''<summary>
        ''' 获取 章
        ''' </summary>
        ''' <param name="comicId"></param>
        ''' <param name="chapterId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetComicChapterById(ByVal comicId As String, ByVal chapterId As String) As ComicContent
            If comicId.IsNotNullOrEmpty AndAlso chapterId.IsNotNullOrEmpty Then

                Dim s As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(s, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return Nothing

                Dim str2 As String = chapterId.Replace(";", "/")
                Dim chapterPath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(Comicpath), UriKind.Absolute), New Uri(str2, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(chapterPath) Then Return Nothing

                Dim content As ComicContent = MakeContent(comicId, Comicpath, ContentType.Chapter, chapterPath)

                Return content
            Else
                Return Nothing
            End If
        End Function

        ''' <summary>
        '''  获取 全部 章
        ''' </summary>
        ''' <param name="comicId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetComicChapters(ByVal comicId As String) As System.Collections.Generic.List(Of ComicContent)
            Dim list As New List(Of ComicContent)

            If comicId.IsNotNullOrEmpty Then

                Dim s As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(s, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return list


                Dim dirs = My.Computer.FileSystem.GetDirectories(Comicpath, FileIO.SearchOption.SearchTopLevelOnly, STR_Chapter)

                For Each d In dirs

                    Dim content As SonOVB.Samples.ComicSyndication.ComicProvider.ComicContent = MakeContent(comicId, Comicpath, ContentType.Chapter, d)


                    list.Add(content)
                Next
            End If

            Return list
        End Function


        ''' <summary>
        ''' 获取 卷
        ''' </summary>
        ''' <param name="comicId"></param>
        ''' <param name="volId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetComicVolById(ByVal comicId As String, ByVal volId As String) As ComicContent
            If comicId.IsNotNullOrEmpty AndAlso volId.IsNotNullOrEmpty Then

                Dim s As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(s, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return Nothing

                Dim str2 As String = volId.Replace(";", "/")
                Dim volPath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(Comicpath), UriKind.Absolute), New Uri(str2, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(volPath) Then Return Nothing

                Dim content As SonOVB.Samples.ComicSyndication.ComicProvider.ComicContent = MakeContent(comicId, Comicpath, ContentType.Vol, volPath)

                Return content
            Else
                Return Nothing
            End If
        End Function



        ''' <summary>
        ''' 获取 全部卷
        ''' </summary>
        Public Overrides Function GetComicVols(ByVal comicId As String) As System.Collections.Generic.List(Of ComicContent)
            Dim list As New List(Of ComicContent)

            If comicId.IsNotNullOrEmpty Then

                Dim s As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(s, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return list


                Dim dirs = My.Computer.FileSystem.GetDirectories(Comicpath, FileIO.SearchOption.SearchTopLevelOnly, STR_Vol)

                For Each d In dirs

                    Dim content As SonOVB.Samples.ComicSyndication.ComicProvider.ComicContent = MakeContent(comicId, Comicpath, ContentType.Vol, d)


                    list.Add(content)
                Next
            End If

            Return list
        End Function

        ''' <summary>
        '''  获取图片 从 章  
        ''' </summary>
        ''' <param name="comicId"></param>
        ''' <param name="chapterId"></param>
        ''' <param name="pictureId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetPictureFromChapter(ByVal comicId As String, ByVal chapterId As String, ByVal pictureId As String) As Picture
            If comicId.IsNotNullOrEmpty AndAlso chapterId.IsNotNullOrEmpty AndAlso pictureId.IsNotNullOrEmpty Then

                Dim str1 As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(str1, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return Nothing

                Dim str2 As String = chapterId.Replace(";", "/")
                Dim chapterPath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(Comicpath), UriKind.Absolute), New Uri(str2, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(chapterPath) Then Return Nothing

                Dim str3 As String = pictureId.Replace(";", "/")
                Dim picturePath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(chapterPath), UriKind.Absolute), New Uri(str3, UriKind.Relative)).AbsolutePath)

                If Not File.Exists(picturePath) Then Return Nothing


                Dim chapterdir = My.Computer.FileSystem.GetDirectoryInfo(chapterPath)

                Dim fi = My.Computer.FileSystem.GetFileInfo(picturePath)


                Return MakePicture(comicId, chapterId, chapterdir.FullName, ContentType.Chapter, fi)
            Else
                Return Nothing
            End If
        End Function


        ''' <summary>
        '''  获取图片 从 卷  
        ''' </summary>
        ''' <param name="comicId"></param>
        ''' <param name="volId"></param>
        ''' <param name="pictureId"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Function GetPictureFromVol(ByVal comicId As String, ByVal volId As String, ByVal pictureId As String) As Picture
            If comicId.IsNotNullOrEmpty AndAlso volId.IsNotNullOrEmpty AndAlso pictureId.IsNotNullOrEmpty Then

                Dim str1 As String = comicId.Replace(";", "/")
                Dim Comicpath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(ComicsPath), UriKind.Absolute), New Uri(str1, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(Comicpath) Then Return Nothing

                Dim str2 As String = volId.Replace(";", "/")
                Dim volPath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(Comicpath), UriKind.Absolute), New Uri(str2, UriKind.Relative)).AbsolutePath)

                If Not Directory.Exists(volPath) Then Return Nothing

                Dim str3 As String = pictureId.Replace(";", "/")
                Dim picturePath As String = HttpUtility.UrlDecode(New Uri(New Uri(MakeBasePath(volPath), UriKind.Absolute), New Uri(str3, UriKind.Relative)).AbsolutePath)

                If Not File.Exists(picturePath) Then Return Nothing


                Dim voldir = My.Computer.FileSystem.GetDirectoryInfo(volPath)

                Dim fi = My.Computer.FileSystem.GetFileInfo(picturePath)


                Return MakePicture(comicId, volId, voldir.FullName, ContentType.Vol, fi)
            Else
                Return Nothing
            End If
        End Function


#End Region

    End Class


End Namespace
